<?php

namespace StudyBuddy\Controllers;

use \StudyBuddy\WebPage;
use \StudyBuddy\String;
use \StudyBuddy\Cookie;
use \StudyBuddy\Request;
use \StudyBuddy\Captcha;
use \StudyBuddy\Mailer;
use StudyBuddy\RegBlockQuickReg;

/**
 * Main class for creating new account
 * for a new user who is registered
 * with just email address (no 3rd party API login)
 *
 * @todo move as many methods as possible to
 * a wrapper class so that it could be called
 * not only as a web page Conroller
 * but also from the API
 * Later it will be easity to reuse if we have the API
 *
 */
class Register extends WebPage
{
	protected $permission = 'register';

	protected $useToken = false;
        
	const EMAIL_BODY = 'Welcome to %1$s!

IMPORTANT: You Must use the link below to activate your account
%4$s

This email contains your login information for %1$s

Your login information is as follows:

    Username: %2$s
    Password: %3$s


You are advised to store the above information in a safe place so that you
do not face any inconvenience in future.

You can change your password after you log in. 


	';

	const SUBJECT = 'Your %s login information';

	/**
	 * Message to show upon completed successful
	 * registration
	 * 
	 * @var string
	 */
	const SUCCESS = 'Welcome to our club.<br>Please check your email and activate your account A.S.A.P.<br>(details are in the email)';

	protected $layoutID = 1;

	/**
	 * Object Regform;
	 *
	 * @var object Forms\Regform
	 */
	protected $oForm;

	/**
	 * New temporary password of new user
	 *
	 * @var string
	 */
	protected $pwd;

	/**
	 * Username of new user
	 *
	 * @var string
	 */
	protected $username;

	/**
	 *
	 * Email address of new user
	 * @var string
	 */
	protected $email;

	/**
	 * Object represents on record in EMAILS collection
	 *
	 * @var object of type MongoDoc
	 */
	protected $oEmail;
        
        protected $oUser;

        protected function main(){
		$this->aPageVars['title'] = $this->_('Create New Account');
		/**
		 * Don't bother with token
		 * for this form.
		 * It uses captcha, so allow
		 * users to submit without token
		 */
		$this->oForm = new \StudyBuddy\Forms\Regform($this->oRegistry, false);
		$this->oForm->setVar('action', 'register');
		/**
		 * Set divID to registration because otherwise
		 * it is default to 'regform' which causes
		 * the whole form's div to be turned into
		 * a modal which is used in quickReg or Join controllers
		 * but for this controller we want a regular web page,
		 * no modals, no Ajax
		 *
		 * Also set className to 'registration' because it defaults
		 * to yui-pre-content which makes the whole div hidden
		 * This is a trick for adding something that later is turned
		 * into modal, but we don't need it for this page
		 */
		$this->oForm->setVar('divID', 'registration');
		$this->oForm->setVar('className', 'registration');
		$this->oForm->setVar('header2', $this->_('Create New Account'));
		$this->oForm->setVar('button', '<input name="submit" value="'.$this->_('Register').'" type="submit" class="btn btn-m">');
		$this->oForm->setVar('captcha', Captcha::factory($this->oRegistry)->getCaptchaBlock());
		$this->oForm->setVar('title', $this->_('Create an Account'));
		$this->oForm->setVar('titleBar', '');

		if($this->oForm->isSubmitted() && $this->oForm->validate()){
			$this->getSubmittedValues()
			->createNewUser()
			->createEmailRecord()
			->sendActivationEmail();
			/**
			 * @todo Translate string
			 */
                        $this->oForm = new \StudyBuddy\Forms\Profile($this->oRegistry, false);
			$this->oForm->setVar('message', '<div id="tools" class="larger" style="margin-top:0; width:475px;">'.self::SUCCESS.'</div>');
			
                        $this->getUser()->setForm();
			$this->aPageVars['body'] = $this->oForm->getForm(false);
//			$this->aPageVars['body'] = '<div id="tools" class="larger">'.self::SUCCESS.'</div>';
		} else {
                    $o = new RegBlockQuickReg($this->oRegistry);
                    $s = $o->makeSocialAuthBlock();
                    $this->oForm->setVar('td2', $s);
			$this->aPageVars['body'] = '<div id="userForm" class="frm1">'.$this->oForm->getForm().'</div>';
		}
	}

	/**
	 * Init instance variables
	 * $this->username, $this->email and $this->pwd
	 *
	 * @return object $this
	 */
	protected function getSubmittedValues(){
		$this->username = $this->oForm->getSubmittedValue('username');
//		$this->pwd = \StudyBuddy\String::makePasswd();
		$this->pwd = $this->oForm->getSubmittedValue('pwd1');
		$this->pwd1 = $this->oForm->getSubmittedValue('pwd1');
		$this->pwd2 = $this->oForm->getSubmittedValue('pwd2');
		$this->email = \mb_strtolower($this->oForm->getSubmittedValue('email'));

		return $this;
	}


	/**
	 *
	 * Create new record in USERS collection,
	 *
	 * @return object $this
	 */
	protected function createNewUser(){

		$coll = $this->oRegistry->Mongo->USERS;
		$coll->ensureIndex(array('username_lc' => 1), array('unique' => true));
		/**
		 * Cannot make email unique index because external users
		 * don't have email, and then value counts as null
		 * and multiple null values count as duplicate!
		 *
		 */
		$coll->ensureIndex(array('email' => 1));
		$coll->ensureIndex(array('role' => 1));
		/**
		 * Indexes for managing 3 types
		 * of following
		 */
		$coll->ensureIndex(array('a_f_t' => 1));
		$coll->ensureIndex(array('a_f_u' => 1));
		$coll->ensureIndex(array('a_f_q' => 1));

		$sid = \StudyBuddy\Cookie::getSidCookie();

		$aData['username'] 		= $this->username;
		$aData['username_lc'] 	= strtolower($this->username);
		$aData['email'] 		= $this->email;
		$aData['rs'] 			= (false !== $sid) ? $sid : \StudyBuddy\String::makeSid();
		$aData['role'] 			= $this->getRole();
		$aData['tz'] 			= \StudyBuddy\TimeZone::getTZbyoffset($this->oRequest->get('tzo'));
		$aData['pwd'] 			= String::hashPassword($this->pwd);
		$aData['i_reg_ts'] 		= time();
		$aData['date_reg']		= date('r');
		$aData['i_fv'] 			= (false !== $intFv = \StudyBuddy\Cookie::getSidCookie(true)) ? $intFv : time();
		$aData['lang'] 			= $this->oRegistry->getCurrentLang();
		$aData['locale'] 		= $this->oRegistry->Locale->getLocale();
		/**
		 * Initial reputation is always 1
		 * @var int
		 */
		$aData['i_rep'] = 1;
		$aUser = array_merge($this->oRegistry->Geo->Location->data, $aData);

		d('aUser: '.print_r($aUser, 1));

		$oUser = \StudyBuddy\User::factory($this->oRegistry, $aUser);
		$oUser->save();
		d('id: '.$oUser['_id']);
		
		$this->processLogin($oUser);

		\StudyBuddy\PostRegistration::createReferrerRecord($this->oRegistry, $oUser);


		return $this;
	}


	/**
	 * Normally the role of newly registered user
	 * is 'unactivated' unless
	 * the email address matches that of the EMAIL_ADMIN
	 * in settings, in which case the account will
	 * automatically become an administrator account
	 *
	 *
	 * @param string $email email address
	 */
	protected function getRole(){

		return ($this->oRegistry->Ini->EMAIL_ADMIN === $this->email) ? 'administrator' : 'unactivated';
	}


	/**
	 * Created a new record in EMAILS collection
	 *
	 * @return object $this
	 */
	protected function createEmailRecord(){

		$coll = $this->oRegistry->Mongo->EMAILS;
		$coll->ensureIndex(array('email' => 1), array('unique' => true));

		$a = array(
			'email' => $this->email,
			'i_uid' => $this->oRegistry->Viewer->getUid(),
			'has_gravatar' => \StudyBuddy\Gravatar::factory($this->email)->hasGravatar(),
			'ehash' => hash('md5', $this->email),
			'i_code_ts' => time(),
			'code' => \substr(hash('md5', \uniqid(\mt_rand())), 0, 12));
		
		$this->oEmail = \StudyBuddy\MongoDoc::factory($this->oRegistry, 'EMAILS', $a);
		
		$res = $this->oEmail->save();
		d('$res: '.$res);
		
		return $this;
	}


	/**
	 * Make account activation link
	 *
	 * @return string url of account activation link
	 */
	protected function makeActivationLink(){
		$tpl = $this->oRegistry->Ini->SITE_URL.'/aa/%d/%s';
		$link = \sprintf($tpl, $this->oEmail['_id'], $this->oEmail['code']);
		d('activation link: '.$link);

		return $link;
	}


	protected function sendActivationEmail(){
		$sActivationLink = $this->makeActivationLink();
		$siteName = $this->oRegistry->Ini->SITE_NAME;
		$body = vsprintf(self::EMAIL_BODY, array($siteName, $this->username, $this->pwd, $sActivationLink));
		$subject = sprintf(self::SUBJECT, $this->oRegistry->Ini->SITE_NAME);

		Mailer::factory($this->oRegistry)->mail($this->email, $subject, $body);

		return $this;
	}
        
        // 
        
        protected function getUser(){
		$uid = $this->oRequest->get('uid', 'i', null);
		if($uid && ($uid !== $this->oRegistry->Viewer->getUid())){
			/**
			 * This is edit profile for another user
			 * check Viewer permission here
			 */
			$this->checkAccessPermission('edit_any_profile');
			$this->oUser = \StudyBuddy\User::factory($this->oRegistry)->by_id($uid);
		} else {
			$this->oUser = $this->oRegistry->Viewer;
		}

		return $this;
	}
        
        protected function setForm(){
                if($this->useToken){
			$this->oForm->token = static::generateToken();
		}
//                
		$this->oForm->tmp_role = $this->getRoleInput();
		$this->oForm->new_reg = '';
		$this->oForm->old_reg = 'display:none';
                
		$this->oForm->username = $this->oUser['username'];
		$this->oForm->usernameLabel = 'Username';
		$this->oForm->fn = $this->oUser['fn'];
		$this->oForm->mn = $this->oUser['mn'];
		$this->oForm->ln = $this->oUser['ln'];
		$this->oForm->fullname = $this->oUser['fullname'];
		$this->oForm->gender = $this->getGenderOptions();
		$this->oForm->dob = $this->oUser['dob'];
		$this->oForm->cc = $this->getCountryOptions();
		$this->oForm->state = $this->oUser['state'];
		$this->oForm->city = $this->oUser['city'];
		$this->oForm->url = $this->oUser['url'];
		$this->oForm->zip = $this->oUser['zip'];
		$this->oForm->description = $this->oUser['description'];
		$this->oForm->sowa = $this->oUser['sowa'];
		$this->oForm->avatarSrc = $this->oUser->getAvatarSrc();
		$this->oForm->width = $this->oRegistry->Ini->AVATAR_SQUARE_SIZE;
		$this->oForm->uid = $this->oUser->getUid();
		$this->oForm->maxAvatarSize = $this->oRegistry->Ini->MAX_AVATAR_UPLOAD_SIZE;
		/**
		 * @todo translate string
		 */
		$this->oForm->avatarTos = sprintf('Upload Image. Maximum size of %sMb<br><span class="smaller">By uploading a file you certify that you have the right to distribute this picture and that it does not violate the Terms of Service.</span>', floor($this->oRegistry->Ini->MAX_AVATAR_UPLOAD_SIZE / 1000000) );

		/**
		 * Add '  hide' class to avatar upload
		 * if php does not have gd of support for jpeg
		 * inside gd
		 */
		if(!\extension_loaded('gd') || !\function_exists('imagecreatefromjpeg')){
			$this->oForm->hideAvatar = ' hide';
		}

		return $this;
	}
        protected function getCountryOptions(){
		$s = '';
		$tpl = '<option value="%1$s"%2$s>%3$s</option>';
		$aCountries = \array_combine(\StudyBuddy\Geo\Location::getCodes(), \StudyBuddy\Geo\Location::getNames());
		
		foreach($aCountries as $key => $val){
			$selected = ('' == $key) ? ' selected' : '';
			$name = (empty($val)) ? 'Select country' : $val;

			$s .= \vsprintf($tpl, array($key, $selected, $name));
		}

		return $s;
	}
        
        protected function getGenderOptions(){
		$s = '';
		$a = array('' => 'Select Gender', 'M' => 'Male', 'F' => 'Female');
		$tpl = '<option value="%1$s"%2$s>%3$s</option>';
		foreach($a as $key => $val){
			$selected = ($key === '') ? ' selected' : '';
			$s .= vsprintf($tpl, array($key, $selected, $val));
		}

		return $s;
	}
        
        protected function getRoleInput(){
            $s = '';
            $a = array('student' => 'Student', 'parent' => 'Parent', 'tutor' => 'Tutor');
            $tpl = '<input type="radio" id="id_tmp_role%1$s" name="tmp_role" value="%2$s"%3$s%5$s /> %4$s ';
            $i = 1;
            foreach ($a as $key => $value){
                $checked = ($key === 'student') ? ' checked="checked"' : '';
                $tutor = ($key == 'tutor') ? ' onclick="window.location=\'http://'.$_SERVER['HTTP_HOST'].'/regtutor\'"' : '';
                $s .= vsprintf($tpl, array($i, $key, $checked, $value, $tutor));
                $i++;
            }
            return $s;
        }
        
	/**
	 * Generate unique ID and store in session
	 * The page will have the meta tag 'version'
	 * with the value of this token
	 * it will be used by ajax based forms when submitting
	 * form via ajax
	 *
	 *
	 * @return string value of form token
	 * for this class.
	 */
	public static function generateToken(){
		if (!array_key_exists('secret', $_SESSION)) {

			$token = uniqid(mt_rand());
			//$_SESSION['secret'] = $token;
			$_SESSION['secret'] = hash('md5', $token);
		}

		return $_SESSION['secret'];
		//return hash('md5', $_SESSION['secret'].get_called_class());
	}


}
